package context

import (
	"bytes"
	"net/http"
	"strconv"

	"yingsheng.com/go-api-server/constant"
	"yingsheng.com/go-api-server/errors"
)

type Response struct {
	Context            *Context
	httpResponseWriter http.ResponseWriter
	result             *Result
	code               int
	msg                string
}

// 创建新的响应对象
func NewResponse() *Response {
	return &Response{
		result: &Result{},
	}
}

// 重置Http响应对象
func (r *Response) Reset(ctx *Context, httpRes http.ResponseWriter) {
	r.Context = ctx
	r.httpResponseWriter = httpRes
	r.code = constant.RESPONSE_CODE_OK
	r.msg = ""

	r.result = NewResult()
}

// 设置错误信息
func (r *Response) Error(options ...interface{}) {
	r.code = constant.RESPONSE_CODE_ERROR
	r.msg = ""

	for i, n := 0, len(options); i < n; i++ {
		switch opt := options[i].(type) {
		case int:
			r.code = opt
		case string:
			r.msg = opt
		case errors.SysErrorInterface:
			// 设置为新的错误代码
			//			if opt.Status() != 0 {
			//				r.code = opt.Status()
			//			}
			r.code = constant.RESPONSE_CODE_CRASH

			if r.Context.IsDev() {
				r.msg = opt.String()
			} else {
				r.msg = opt.Error()
			}

			// 记录错误日志
			r.Context.ChainError(opt.String())
		case errors.NormalErrorInterface:
			if opt.Status() != 0 {
				r.code = opt.Status()
			}

			r.msg = opt.Error()
		case error:
			r.msg = opt.Error()
		}
	}

	r.systemError()
}

// 自定义系统错误说明
func (r *Response) systemError() {
	msg := constant.GetResponseMsg(r.code)

	if len(msg) > 0 {
		r.msg = msg
	}
}

// 结果转Json格式输出页面内容
func (r *Response) WriteJson() {
	var (
		json []byte
		err  error
	)

	if err == nil {
		json, err = r.result.ToJson(r.Context.IsDev())
		if err != nil {
			err = errors.NewSys(err)
			r.Error(err)
			json = []byte{'{', '}'}
		}
	}

	buff := bytes.NewBuffer([]byte(`{"code":`))
	buff.WriteString(strconv.Itoa(r.code))
	buff.WriteString(`,"msg":"`)
	buff.WriteString(r.msg)
	buff.WriteString(`","data":`)
	buff.Write(json)

	buff.WriteByte('}')

	r.Write(buff.Bytes())

	r.Context.ChainResponse(buff.String())
}

// 输出错误头信息，如500
func (r *Response) WriteError(status int) {
	http.Error(r.httpResponseWriter, "", status)
}

// 输出页面内容
// contentType可选：json（默认）,text,html,gif,jpeg,png
func (r *Response) Write(content []byte, conentType ...string) {
	tk, tv := "", "application/json; charset=utf-8"

	if len(conentType) == 1 {
		tk = conentType[0]
		switch tk {
		case "text":
			tv = "application/x-www-form-urlencoded"
		case "html":
			tv = "text/html"
		case "gif":
			tv = "image/gif"
		case "jpeg":
			tv = "image/jpeg"
		case "png":
			//兼容IE浏览器
			//tv = "image/x-png"
			tv = "image/png"
		}
	}

	r.httpResponseWriter.Header().Set("Content-Type", tv)
	r.httpResponseWriter.Write(content)
}

// 引用结果对象
func (r *Response) Result() *Result {
	return r.result
}

// 获取原生http.ResponseWriter对象
func (r *Response) HttpResponseWriter() *http.ResponseWriter {
	return &r.httpResponseWriter
}
